OPC Studio User's Guide and Reference
Examples - OPC XML-DA - Get values of multiple properties
View with Navigation Tools

Basic Example

// This example shows how to get value of multiple OPC XML-DA properties, and handle errors.
//
// Note that some properties may not have a useful value initially (e.g. until the item is activated in a group), which also the
// case with Timestamp property as implemented by the demo server. This behavior is server-dependent, and normal. You can run 
// IEasyDAClient.ReadMultipleItemValues.Main.vbs shortly before this example, in order to obtain better property values. Your 
// code may also subscribe to the items in order to assure that they remain active.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using OpcLabs.BaseLib.OperationModel;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.OperationModel;

namespace DocExamples.DataAccess.Xml
{
    partial class GetMultiplePropertyValues
    {
        public static void Main1Xml()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            ServerDescriptor serverDescriptor = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx";

            // Get the values of Timestamp and AccessRights properties of two items.
            ValueResult[] results = client.GetMultiplePropertyValues(new[]
            {
                new DAPropertyArguments(serverDescriptor, "Dynamic/Analog Types/Int", DAPropertyDescriptor.Timestamp),
                new DAPropertyArguments(serverDescriptor, "Dynamic/Analog Types/Int", DAPropertyDescriptor.AccessRights),
                new DAPropertyArguments(serverDescriptor, "Static/Analog Types/Double", DAPropertyDescriptor.Timestamp),
                new DAPropertyArguments(serverDescriptor, "Static/Analog Types/Double", DAPropertyDescriptor.AccessRights)
            });

            for (int i = 0; i < results.Length; i++)
            {
                ValueResult valueResult = results[i];
                if (valueResult.Exception is null)
                    Console.WriteLine($"results({i}).Value: {valueResult.Value}");
                else
                    Console.WriteLine($"results({i}).Exception.Message: {valueResult.Exception.Message}");
            }
        }
    }
}

Example combined with item browsing

The example below is a bit more complex, and combines the ability to browse for items with getting the the data type property for each of the items obtained, for OPC XML-DA Servers.

.NET

// This example shows how to obtain a data type of all OPC XML-DA items under a branch.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using System.Linq;
using OpcLabs.BaseLib.ComInterop;
using OpcLabs.BaseLib.OperationModel;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;

namespace DocExamples.DataAccess.Xml
{
    partial class GetMultiplePropertyValues
    {
        public static void DataTypeXml()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            ServerDescriptor serverDescriptor = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx";

            // Browse for all leaves under the "Static/Analog Types" branch
            DANodeElementCollection nodeElementCollection = client.BrowseLeaves(serverDescriptor, "Static/Analog Types");

            // Create list of node descriptors, one for each leaf obtained
            DANodeDescriptor[] nodeDescriptorArray = nodeElementCollection
                .Where(element => !element.IsHint)  // filter out hint leafs that do not represent real OPC items (rare)
                .Select(element => new DANodeDescriptor(element))
                .ToArray();

            // Get the value of DataType property; it is a 16-bit signed integer
            ValueResult[] valueResultArray = client.GetMultiplePropertyValues(serverDescriptor,
                nodeDescriptorArray, DAPropertyIds.DataType);

            for (int i = 0; i < valueResultArray.Length; i++)
            {
                DANodeDescriptor nodeDescriptor = nodeDescriptorArray[i];

                // Check if there has been an error getting the property value
                ValueResult valueResult = valueResultArray[i];
                if (!(valueResult.Exception is null))
                {
                    Console.WriteLine("{0} *** Failure: {1}", nodeDescriptor.NodeId, valueResult.Exception.Message);
                    continue;
                }

                // Convert the data type to VarType
                var varType = (VarType)(short)valueResult.Value;

                // Display the obtained data type
                Console.WriteLine("{0}: {1}", nodeDescriptor.ItemId, varType);
            }
        }
    }
}

COM

// This example shows how to obtain a data type of all OPC XML-DA items under a branch.
//
// Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

class procedure GetMultiplePropertyValues.DataTypeXml;
var
  Arguments: OleVariant;
  BrowseParameters: _DABrowseParameters;
  Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
  Count: Cardinal;
  Element: OleVariant;
  I: Cardinal;
  PropertyArguments: _DAPropertyArguments;
  ServerDescriptor: _ServerDescriptor;
  NodeDescriptor: _DANodeDescriptor;
//  NodeDescriptorArray: Array of DANodeDescriptor;
  NodeElement: _DANodeElement;
  NodeElementCollection: _DANodeElementCollection;
  NodeElementEnumerator: IEnumVariant;
  ValueResult: _ValueResult;
  ValueResultArray: OleVariant;
  VarType: _VarType;
begin
  ServerDescriptor := CoServerDescriptor.Create;
  ServerDescriptor.UrlString := 'http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx';

  NodeDescriptor := CoDANodeDescriptor.Create;
  NodeDescriptor.ItemId := 'Static/Analog Types';

  BrowseParameters := CoDABrowseParameters.Create;
  BrowseParameters.BrowseFilter := DABrowseFilter_Leaves;

  // Instantiate the client object
  Client := CoEasyDAClient.Create;

  // Browse for all leaves under the "Static/Analog Types" branch
  NodeElementCollection := Client.BrowseNodes(
      ServerDescriptor,
      NodeDescriptor,
      BrowseParameters);


  // Create list of node descriptors, one for aeach leaf obtained
  I := 0;
  Arguments := VarArrayCreate([0, NodeElementCollection.Count - 1], varVariant);
  NodeElementEnumerator := NodeElementCollection.GetEnumerator;
  while (NodeElementEnumerator.Next(1, Element, Count) = S_OK) do
  begin
    NodeElement := IUnknown(Element) as _DANodeElement;
    // filter out hint leafs that do not represent real OPC XML-DA items (rare)
    if Not NodeElement.IsHint then
    begin
      PropertyArguments := CoDAPropertyArguments.Create;
      PropertyArguments.ServerDescriptor := ServerDescriptor;
      PropertyArguments.NodeDescriptor := NodeElement.ToDANodeDescriptor;
      PropertyArguments.PropertyDescriptor.PropertyId.InternalValue := DAPropertyIds_DataType;
      Arguments[I] := PropertyArguments;
      I := I + 1;
    end;
  end;
//  SetLength(Arguments, I);

  // Get the value of DataType property; it is a 16-bit signed integer
  TVarData(ValueResultArray).VType := varArray or varVariant;
  TVarData(ValueResultArray).VArray := PVarArray(
    Client.GetMultiplePropertyValues(Arguments));

  // Display results
  for I := VarArrayLowBound(ValueResultArray, 1) to VarArrayHighBound(ValueResultArray, 1) do
  begin
      ValueResult := IInterface(ValueResultArray[I]) as _ValueResult;

      // Check if there has been an error getting the property value
      if ValueResult.Exception <> nil then
      begin
        WriteLn(Format('s *** Failures', [Arguments[I].NodeDescriptor.NodeId, ValueResult.Exception.Message]));
        Continue;
      end;

      // Convert the data type to VarType
      VarType := CoVarType.Create;
      VarType.InternalValue := ValueResult.Value;

      // Display the obtained data type
      WriteLn(Format('s: s', [Arguments[I].NodeDescriptor.NodeId, VarType.ToString]));
  end;
  VarClear(ValueResultArray);
  VarClear(Arguments);
end;

 

QuickOPC supports OPC XML-DA also on Linux and macOS.
See Also

Examples - OPC Data Access

Conceptual